/* /////////////////////////////////////////////////////////////////////////////
 * File:        sample2.d
 *
 * Purpose:     色々実験…よく書き換わる意味のないコードです。
 *
 * Created      22th June 2007
 * Updated:     22th June 2007
 *
 * www:         http://
 *
 * Copyright (C) 2007 by Yasunobu Imamura
 *
 * This software is provided 'as-is', without any express or implied warranty.
 * In no event will the authors be held liable for any damages arising from the
 * use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not claim
 * that you wrote the original software. If you use this software in a product,
 * an acknowledgment in the product documentation would be appreciated but is
 * not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source distribution. 
 *
 * ////////////////////////////////////////////////////////////////////////// */

module sample;

private import std.stdio;
private import std.stream;
private import gtree.all;
private import std.random;

char[] MakeRandomString(int len, int alpha)
{
	char[] ret = new char[len];
	for(int i=0; i<len; ++i)
	{
		ret[i] = 'A' + (rand() % alpha);
	}
	return ret;
}

double[] MakeRandomTupple(int len)
{
	double[] ret = new double[len];
	for(int i=0; i<len; ++i)
	{
		ret[i] = (rand() % 1000000) / 1000000.0;
	}
	return ret;
}

void TestSED(out double avg, out double st, int len, int alpha, int n = 10000)
{
	alias StringFeature!(char, StringEditDistanceNorm) FtrType;

	int sum = 0;
	int sum2 = 0;

	for(int i=0; i<n; ++i)
	{
		FtrType a = new FtrType(MakeRandomString(len, alpha));
		FtrType b = new FtrType(MakeRandomString(len, alpha));
		int d = a.distance(b);
		sum += d;
		sum2 += d*d;
	}
	avg = (cast(double)sum) / n;
	st = (sum2 - sum * avg) / n;
}

void TestTupple(alias Norm)(out double avg, out double st, int len, int n = 10000)
{
	alias TuppleFeature!(double, Norm) FtrType;

	double sum = 0;
	double sum2 = 0;

	for(int i=0; i<n; ++i)
	{
		FtrType a = new FtrType(MakeRandomTupple(len));
		FtrType b = new FtrType(MakeRandomTupple(len));
		double d = a.distance(b);
		sum += d;
		sum2 += d*d;
	}
	avg = (cast(double)sum) / n;
	st = (sum2 - sum * avg) / n;
}

void main()
{
	double avg;
	double st;

	int n = 100000;

	writefln("== L1 ==");
	for(int i=1; i<=60; ++i)
	{
		TestTupple!(L_1Norm)(avg, st, i, n);
		writefln("L1\t", i, "\t", avg, "\t", st);
	}

	writefln("== L2 ==");
	for(int i=1; i<=60; ++i)
	{
		TestTupple!(L_2Norm)(avg, st, i, n);
		writefln("L2\t", i, "\t", avg, "\t", st);
	}

	writefln("== L_infty ==");
	for(int i=1; i<=60; ++i)
	{
		TestTupple!(L_inftyNorm)(avg, st, i, n);
		writefln("Linfty\t", i, "\t", avg, "\t", st);
	}

	for(int j=2; j<=100; ++j)
	{
		writefln("== StringEditDistance ", j, " ==");
		for(int i=1; i<=60; ++i)
		{
			TestSED(avg, st, i, j, n);
			writefln("SED", j, "\t", i, "\t", avg, "\t", st);
		}
	}
}
